/******************************************************************************************************
Copyright (C) 2008 Mestrelab Research S.L. All rights reserved.

This file is part of the MNova scripting toolkit.

Authorized users of MNova Software may use this file freely, but this file is provided AS IS
with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.
*****************************************************************************************************/

/*globals
        Application, print, DBPlugin, ProgressDialog, Settings, MnUi, qsTr */
/*jslint plusplus: true, indent: 4*/


function dbOptimize() {
    "use strict";

    var totalTimeStart, query, result, c, i, q, r, hits, startTime, endTime, time,

        molQuery1 = {                            // 1st Molecule of Wiley CNMR
            name: "molQuery1",
            searchType: "CHEMSTRC",
            itemType: "",
            fieldName: "",
            minHitQuality: 1000,
            query: "\n"
                + "  Mnova   03311411512D\n"
                + "\n"
                + " 15 17  0  0  0  0  0  0  0  0999 V2000\n"
                + "   47.5833  -79.7967    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n"
                + "    0.0000  -79.7967    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "    0.0000  -93.2633    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "   11.8600  -73.0600    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "   72.1800  -80.3800    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "   83.3067  -74.0833    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "   23.7200  -93.2633    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "   23.7200  -79.7967    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "   92.5333  -61.6400    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "  100.0000  -74.0833    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "   11.8600 -100.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "   72.1800  -94.2900    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "   35.7267  -73.0600    0.0000 S   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "   60.1733  -72.7667    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + "   47.5833  -93.2633    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0\r\n"
                + " 15  1  2  0  0  0  0\r\n"
                + " 14  1  1  0  0  0  0\r\n"
                + " 13  1  1  0  0  0  0\r\n"
                + "  5 14  1  0  0  0  0\r\n"
                + "  6  5  1  0  0  0  0\r\n"
                + "  7 15  1  0  0  0  0\r\n"
                + "  8 13  1  0  0  0  0\r\n"
                + "  9  6  1  0  0  0  0\r\n"
                + " 10  6  1  0  0  0  0\r\n"
                + " 12  5  2  0  0  0  0\r\n"
                + " 11  7  1  0  0  0  0\r\n"
                + "  4  8  1  0  0  0  0\r\n"
                + "  3 11  2  0  0  0  0\r\n"
                + "  2  4  2  0  0  0  0\r\n"
                + "  8  7  2  0  0  0  0\r\n"
                + "  2  3  1  0  0  0  0\r\n"
                + "  9 10  1  0  0  0  0\r\n"
                + "M  END"
        },

        peaksQuery1 = {
            name: "peaksQuery1",
            searchType: "PEAKLIST1A",
            itemType: "",
            fieldName: "",
            minHitQuality: 600,
            query: "7 MODE: PURITY\n"               // 1st Spectrum of WileyCNMR
                + "1 Px: 146.100 148.100\n"
                + "2 Px: 144.000 146.000\n"
                + "3 Px: 87.0000 89.0000\n"
                + "4 Px: 44.6000 46.6000\n"
                + "5 Px: 30.3000 32.3000\n"
                + "6 Px: 18.4000 20.4000\n"
                + "7 Px: 12.7000 14.7000"
        },

        peaksQuery2 = {                             // 1st spectrum of WileyHNMR
            name: "peaksQuery2",
            searchType: "PEAKLIST1A",
            itemType: "",
            fieldName: "",
            minHitQuality: 600,
            query: "25 MODE: PURITY\n"
                + "1 Px: 12.3140 12.5140\n"
                + "2 Px: 7.76800 7.96800\n"
                + "3 Px: 7.74200 7.94200\n"
                + "4 Px: 7.60800 7.80800\n"
                + "5 Px: 7.58100 7.78100\n"
                + "6 Px: 7.30800 7.50800\n"
                + "7 Px: 7.28400 7.48400\n"
                + "8 Px: 7.25900 7.45900\n"
                + "9 Px: 7.17500 7.37500\n"
                + "10 Px: 7.14900 7.34900\n"
                + "11 Px: 7.12400 7.32400\n"
                + "12 Px: 2.97800 3.17800\n"
                + "13 Px: 2.43900 2.63900\n"
                + "14 Px: 2.40400 2.60400\n"
                + "15 Px: 1.97100 2.17100\n"
                + "16 Px: 1.95400 2.15400\n"
                + "17 Px: 1.94600 2.14600\n"
                + "18 Px: 1.93200 2.13200\n"
                + "19 Px: 1.91700 2.11700\n"
                + "20 Px: 1.90700 2.10700\n"
                + "21 Px: 1.89000 2.09000\n"
                + "22 Px: 0.895000 1.09500\n"
                + "23 Px: 0.853000 1.05300\n"
                + "24 Px: 0.826000 1.02600\n"
                + "25 Px: 0.800000 1.00000\n"
        },

        txtQuery1 = {
            name: "txtQuery1",
            searchType: "TEXT",
            itemType: "",
            fieldName: "",
            minHitQuality: 600,
            query: "benzothiazol"
        },

        queries = [ molQuery1, peaksQuery1, peaksQuery2, txtQuery1 ],
        results = [],
        iterations = 3,
        db = DBPlugin.client,
        progress = new ProgressDialog();

    function dbPluginSearch(aDB, aQuery) {
        var settings = new Settings("DBSearch/Settings"),
            maxHits = settings.value("MaxHits", 100),
            maxRecords = settings.value("MaxRecords", 100);
        return DBPlugin.search(aDB, aQuery.query, aQuery.searchType, aQuery.itemType, aQuery.fieldName, maxHits, maxRecords, aQuery.minHitQuality);
    }

    function showResults() {

        var ui = '<?xml version="1.0" encoding="UTF-8"?>'
                + '<ui version="4.0">'
                + '<class>Dialog</class>'
                + '  <widget class="QDialog" name="Dialog">'
                + '    <property name="geometry"><rect><x>0</x><y>0</y><width>550</width><height>300</height></rect></property>'
                + '    <property name="windowTitle"><string>Optimize Query Results</string></property>'
                + '    <layout class="QVBoxLayout" name="verticalLayout">'
                + '    <item>'
                + '      <widget class="QTableWidget" name="tableWidget">'
                + '      </widget>'
                + '    </item>'
                + '    <item>'
                + '      <widget class="QLabel" name="label">'
                + '        <property name="text"><string>Hello</string></property>'
                + '      </widget>'
                + '    </item>'
                + '    <item>'
                + '      <widget class="QDialogButtonBox" name="buttonBox">'
                + '        <property name="orientation"><enum>Qt::Horizontal</enum></property>'
                + '        <property name="standardButtons"><set>QDialogButtonBox::Ok</set></property>'
                + '      </widget>'
                + '    </item>'
                + '  </layout>'
                + '</widget>'
                + '<resources/>'
                + '<connections>'
                + '   <connection>'
                + '      <sender>buttonBox</sender>'
                + '      <signal>accepted()</signal>'
                + '      <receiver>Dialog</receiver>'
                + '      <slot>accept()</slot>'
                + '      <hints><hint type="sourcelabel"><x>248</x><y>254</y></hint><hint type="destinationlabel"><x>157</x><y>274</y></hint></hints>'
                + '   </connection>'
                + '</connections></ui>',
            dialog = Application.loadUi(ui),
            tableWidget = dialog.widgets.tableWidget,
            horzHeaderItems = [{'text': 'Query 1'}, {'text': 'Hits'}];

        tableWidget.editTriggers = 0;
        tableWidget.rowCount = results.length;
        tableWidget.columnCount = results[0].times.length + 2;
        for (i = 0; i < results[0].times.length; i++) {
            horzHeaderItems.push({'text': "i=" + (i + 1)});
        }
        tableWidget.horzHeaderItems = horzHeaderItems;
        // Alignments:
        // 130 = 0x82 = Right | VCenter
        // 132 = 0x84 = HCenter | VCenter
        for (r = 0; r < results.length; r++) {
            tableWidget.setItem(r, 0, results[r].query);
            tableWidget.setItem(r, 1, { 'text': results[r].hits, 'textAlignment': 132});
            for (c = 0; c < results[r].times.length; c++) {
                tableWidget.setItem(r, c + 2, {'text': results[r].times[c].toFixed(1) + "s", 'textAlignment': 130});
            }
        }
        dialog.widgets.label.text = db.host + ":" + db.port + "/" + db.database + ": All done in " + ((new Date() - totalTimeStart) / 1000).toFixed(1) + "s.";
        dialog.widgets.buttonBox.centerButtons = true;
        dialog.exec();
    }


    Application.mainWindow.doAction("dbDatabaseOpen");
    if (!db.connected()) {
        // Connection dialog was canceled
        return;
    }
    print(db.toString());
    totalTimeStart = new Date();
    progress.setRange(1, iterations * queries.length + 1);
    progress.show();

    for (q = 0; q < queries.length; q++) {
        if (progress.wasCanceled || !db.connected()) {
            break;
        }
        query = queries[q];
        result = { 'query': query.name, 'times': [] };
        print("Query " + query.name);
        for (i = 0; i < iterations; i++) {
            if (progress.wasCanceled || !db.connected()) {
                break;
            }
            print("    i=" + i);
            // Update progress dialog
            progress.value = q * iterations + i + 1;
            progress.labelText = qsTr("Query {0} of {1} ({2}): Iteration {3} of {4}...").format(q + 1, queries.length, query.name, i + 1, iterations);
            startTime = new Date();
            hits = dbPluginSearch(db, queries[q]);
            endTime = new Date();
            time = (endTime - startTime) / 1000;
            print("      hits: " + hits.length + " time: " + time + "s");
            //for (h = 0; h < peakHits.length; h++) {
            //    print("    Hit: " + peakHits.at(h).toString());
            //}
            result.hits = hits.length;
            result.times[i] = time;
        }
        results[q] = result;
    }
    progress.close();
    print(results);
    showResults(results);
}

if (this.MnUi && MnUi.scripts_db) {
    MnUi.scripts_db.scripts_db_Optimize = dbOptimize;
}
